﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Krist_em_up.Components;
using Microsoft.Xna.Framework.Input;
using ZoomEngine.Animation;


namespace Krist_em_up.Interface
{
    class Menu : GameScreen
    {
        protected List<TextureButton> buttons;
        protected SpriteBatch spriteBatch;
        protected int buttonIndex;
        protected GameStateManager game;

        protected ClockManager clockManager;

        /// <summary>
        /// Krist'em'up Logo
        /// </summary>
        Texture2D logo;

        protected bool CanUpdate;

        public Menu(GameStateManager game)
            : base(game)
        {
            this.game = game;
            CanUpdate = true;
            clockManager = new ClockManager(game);
        }
        /// <summary>
        /// Initialize buttons
        /// </summary>
        public override void Initialize()
        {
            buttons = new List<TextureButton>();
            ResetButtons();
        }

        /// <summary>
        /// Load textures
        /// </summary>
        public override void LoadContent()
        {
            spriteBatch = new SpriteBatch(game.GraphicsDevice);
            logo = game.Content.Load<Texture2D>("Logo");
        }

        public override void UnloadContent()
        {
            
        }

        /// <summary>
        /// Set focus on next button
        /// </summary>
        public void NextButton()
        {
            buttons.ElementAt(buttonIndex).Unfocus();
            buttonIndex = (buttonIndex + 1) % (buttons.Count);
            buttons.ElementAt(buttonIndex).Focus();
        }

        /// <summary>
        /// Set focus on previous button
        /// </summary>
        public void PrevButton()
        {
            buttons[(buttonIndex)].Unfocus();
            buttonIndex = buttonIndex - 1;
            if (buttonIndex < 0)
                buttonIndex = buttons.Count - 1;
            buttons.ElementAt(buttonIndex).Focus();
        }

        /// <summary>
        /// Update the menu
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Update(GameTime gameTime)
        {
            Clavier kb = ((GameStateManager) game).getClavier();
            bool prev = CanUpdate;
            CanUpdate |= !kb.IsKeyDown(Keys.Enter);
            clockManager.Update(gameTime);
            if (CanUpdate &&  prev == CanUpdate)
            {
                if (kb.HasBeenPressed(Keys.Up))
                    PrevButton();
                else if (kb.HasBeenPressed(Keys.Down))
                    NextButton();
                if (kb.HasBeenPressed(Keys.Enter))
                {
                    buttons[buttonIndex].OnSelected();
                }
            }

            foreach (Button b in buttons)
            {
                b.Update(gameTime);
            }
            
        }

        /// <summary>
        /// Draw the menu on the screen
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Draw(GameTime gameTime)
        {
            foreach (TextureButton b in buttons)
            {
                b.Draw(spriteBatch);
            }
            spriteBatch.Begin();
            spriteBatch.Draw(logo, new Vector2(game.graphics.PreferredBackBufferWidth / 2- logo.Width/2, 0), null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f);
            spriteBatch.End();
        }

        public override void Reset()
        {
            ResetButtons();
        }
        /// <summary>
        /// Reset buttons states and restart the animation
        /// </summary>
        protected void ResetButtons()
        {
            buttons.Clear();
            buttonIndex = 0;
            Texture2D jouer = game.Content.Load<Texture2D>("Menu/jouer");
            float y = game.graphics.PreferredBackBufferHeight / 2 - jouer.Height/ 4;
            TextureButton b = new TextureButton(jouer,
                new Vector2(-jouer.Width,
                   y));
            b.Selected += PlayGameMenuEntrySelected;
            buttons.Add(b);
            b = new TextureButton(game.Content.Load<Texture2D>("Menu/options"),
                new Vector2(game.graphics.PreferredBackBufferWidth + jouer.Width,
                    y + jouer.Height / 2 + 20));
            b.Selected += OpenOptionsMenuEntrySelected;
            buttons.Add(b);
            b = new TextureButton(game.Content.Load<Texture2D>("Menu/quitter"),
               new Vector2(-jouer.Width,
                  y + jouer.Height / 2 + jouer.Height /2  + 40));
            b.Selected += ExitGameMenuEntrySelected;
            buttons.Add(b);
            
            for (int i = 0; i < buttons.Count; i++)
            {
                var item = buttons[i];
                var positionAnimation = new Vector2FromToAnimation(clockManager)
                {
                    From = item.Position,
                    To = new Vector2(game.graphics.PreferredBackBufferWidth / 2 - jouer.Width / 2, item.Position.Y),
                    Duration = 1.5,
                    ProgressTransform = ProgressTransforms.Snake,
                    BeginOffset = 0.25 * i,
                    Apply = (v) => item.Position = v,
                };
                positionAnimation.Start();
                
            }
            buttons.ElementAt(0).Focus();
        }

        /// <summary>
        /// Launch the game
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Event arguments</param>
        void PlayGameMenuEntrySelected(object sender, EventArgs e)
        {
            game.SelectPlayMode();
        }
        /// <summary>
        /// Exit the game
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ExitGameMenuEntrySelected(object sender, EventArgs e)
        {
            game.Exit();
        }
        /// <summary>
        /// Open the options menu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OpenOptionsMenuEntrySelected(object sender, EventArgs e)
        {
            CanUpdate = false;
            game.Options();
        }
    }
}
